/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 artifact.h

	$Header: /heroes4/artifact.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( ARTIFACT_H_INCLUDED )
#define ARTIFACT_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#pragma warning( disable: 4786 )

#include <vector>
#include "artifact_effect.h"
#include "artifact_effect_type.h"
#include "artifact_effect_ptr.h"
#include "artifact_effect_visitor.h"
#include "artifact_type.h"

enum  t_artifact_level;
enum  t_artifact_slot;
enum  t_artifact_type;
enum  t_artifact_effect_type;
class t_artifact_effect_visitor;

class t_artifact_effect_list : public std::vector<t_artifact_effect_ptr>
{
};

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
class t_artifact
{
public:
	t_artifact();

	bool						  accept( t_artifact_effect_visitor& visitor ) const;
	t_artifact_effect_list const& get_effects() const;
	std::string					  get_help_text() const;
	t_artifact_type               get_icon() const;
	std::string					  get_name( bool include_article = false ) const;
	t_artifact_level			  get_level() const;
	std::string                   get_pickup_text() const;
	t_artifact_slot				  get_slot() const;
	bool						  has_effect( t_artifact_effect_type ) const;
	bool						  is_empty() const;
	bool						  is_potion() const;
	bool						  is_wand() const;
	bool						  read( std::streambuf& buffer );
	bool						  write( std::streambuf& buffer ) const;
	void						  set_effects( t_artifact_effect_list const& list );
	void						  set_icon( t_artifact_type );
	void						  set_help_text( std::string text );
	void                          set_name( std::string text );
	void                          set_name_with_article( std::string text );
	void                          set_level( t_artifact_level level );
	void                          set_pickup_text( std::string const& text );
protected:
	t_artifact_level       m_level;
	t_artifact_type        m_icon;
	t_artifact_effect_list m_effects;
	std::string            m_help_text;
	std::string            m_name;
	std::string            m_name_with_article;
	std::string            m_pickup_text;
};

class t_artifact_list : public std::vector<t_artifact>
{
};

inline t_artifact_effect_list const& t_artifact::get_effects() const
{
	return m_effects;
}

inline std::string t_artifact::get_help_text() const
{
	return m_help_text;
}

inline t_artifact_type t_artifact::get_icon() const
{
	return m_icon;
}

inline t_artifact_level t_artifact::get_level() const
{
	return m_level;
}

inline std::string t_artifact::get_name( bool include_article ) const
{
	if (include_article)
		return m_name_with_article;
	return m_name;
}

inline std::string t_artifact::get_pickup_text() const
{
	return m_pickup_text;
}

inline bool t_artifact::is_wand() const
{
	return( m_icon >= k_artifact_wand_of_animate_dead && m_icon <= k_artifact_wand_of_weakness );
}

inline void t_artifact::set_effects( t_artifact_effect_list const& list )
{
	m_effects = list;
}

inline void t_artifact::set_icon( t_artifact_type icon )
{
	m_icon = icon;
}

inline void t_artifact::set_level( t_artifact_level level )
{
	m_level = level;
}

inline void t_artifact::set_help_text( std::string text )
{
	m_help_text = text;
}

inline void t_artifact::set_name( std::string text )
{
	m_name = text;
}

inline void t_artifact::set_name_with_article( std::string text )
{
	m_name_with_article = text;
}

inline void t_artifact::set_pickup_text( std::string const& text )
{
	m_pickup_text = text;
}

// ----------------------------------------------------------
// class which represents an instantiated artifact.
// ----------------------------------------------------------
inline bool t_artifact::accept( t_artifact_effect_visitor& visitor ) const
{
	if (m_effects.empty())
		return false;

	int i=0;
	int size  =  m_effects.size();

	visitor.set_artifact( this );

	while(i<size)
	{
		if (m_effects[i]->accept( visitor ))
			return true;

		i++;
	}

	return false;
}

inline bool t_artifact::is_empty() const
{
	return m_effects.empty();
}

#endif // ARTIFACT_H_INCLUDED